﻿// -----------------------------------------------------------------------
// <copyright file="EmployeeService.cs" company="AGR">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace AGR.Services.Employee.Contract
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Linq.Expressions;
    using AGR.Data.Repository;
    using AGR.Model;
    using AGR.Data.Repository.Contract;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class EmployeeService : IEmployeeService
    {
        private ContextHelper _contextHelper;

        private IRepository<Employee> _employeeRepository;

        public EmployeeService()
        {
            _contextHelper = ContextHelper.GetInstance();
            _employeeRepository = new EmployeeRepository(_contextHelper);
        }

        #region Private Methods

        private static void ActionResultError(ActionResult actionResult, Exception ex)
        {
            actionResult.Exception = ex;
            actionResult.IsSystemFailure = true;
            actionResult.Success = false;
        }

        #endregion

        public Employee GetEmployee(string employeeCode)
        {
            if (string.IsNullOrEmpty(employeeCode))
                throw new ArgumentNullException(employeeCode);

            return _employeeRepository.FindSingleBy(x => x.EmployeeCode == employeeCode);
        }

        public Employee GetEmployee(Expression<Func<Employee, bool>> predicate)
        {
            if (predicate == null)
                throw new ArgumentNullException(predicate.ToString());

            return _employeeRepository.FindSingleBy(predicate);
        }

        public IList<Employee> GetAllEmployees()
        {
            return _employeeRepository.GetAll().ToList();
        }

        public IList<Employee> GetAllEmployees(Expression<Func<Employee, bool>> predicate)
        {
            if (predicate == null)
                throw new ArgumentNullException(predicate.ToString());

            return _employeeRepository.GetAll().Where(predicate).ToList();
        }

        public ActionResult AddEmployee(Employee entity)
        {
            if (entity == null)
                throw new ArgumentNullException(entity.EmployeeCode);
            if (string.IsNullOrEmpty(entity.EmployeeCode))
                throw new ArgumentNullException(entity.EmployeeCode);
            if (string.IsNullOrEmpty(entity.UserCreated))
                throw new ArgumentNullException(entity.UserCreated);

            ActionResult actionResult = new ActionResult();

            try
            {
                _employeeRepository.Add(entity);
                _employeeRepository.SaveChanges();

                actionResult.Success = true;
                actionResult.Message = actionResult.RecordInserted;

            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericAddErrorMessage;
            }

            return actionResult;
        }

        public ActionResult UpdateEmployee(Employee entity)
        {
            if (entity == null)
                throw new ArgumentNullException(entity.EmployeeCode);
            if (string.IsNullOrEmpty(entity.EmployeeCode))
                throw new ArgumentNullException(entity.EmployeeCode);
            if (string.IsNullOrEmpty(entity.UserCreated))
                throw new ArgumentNullException(entity.UserModified);

            ActionResult actionResult = new ActionResult();

            try
            {
                _employeeRepository.Update(entity);
                _employeeRepository.SaveChanges();

                actionResult.Success = true;
                actionResult.Message = actionResult.RecordUpdated;
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericUpdateErrorMessage;
            }

            return actionResult;
        }

        public ActionResult DeleteEmployee(string employeeCode)
        {
            if (string.IsNullOrEmpty(employeeCode))
                throw new ArgumentNullException(employeeCode);

            ActionResult actionResult = new ActionResult();

            try
            {
                _employeeRepository.DeleteBy(x => x.EmployeeCode == employeeCode);
                _employeeRepository.SaveChanges();

                actionResult.Success = true;
                actionResult.Message = actionResult.RecordDeleted;
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage;
            }

            return actionResult;
        }

        public ActionResult DeleteEmployee(System.Linq.Expressions.Expression<Func<Employee, bool>> predicate)
        {
            if (predicate == null)
                throw new ArgumentNullException(predicate.ToString());

            ActionResult actionResult = new ActionResult();

            try
            {
                _employeeRepository.DeleteBy(predicate);
                _employeeRepository.SaveChanges();

                actionResult.Success = true;
                actionResult.Message = actionResult.RecordDeleted;
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage;
            }

            return actionResult;
        }

        #region Dispose

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    if (_contextHelper != null)
                        _contextHelper.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}
